package com.central.apps.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.central.app.common.util.WordToPdfUtil;
import com.central.app.entity.TBFile;
import com.central.app.service.CheckConNodeService;
import com.central.app.service.HandlerService;
import com.central.apps.common.util.DateUtiles;
import com.central.apps.common.util.FileUtil;
import com.central.apps.handler.contract.FileSynUtilService;
import com.central.apps.service.OnlineEditService;
import com.central.apps.util.POIUtil;
import com.central.apps.util.worldUtil;
import com.central.common.auth.details.LoginAppUser;
import com.central.common.util.ResponseUtil;
import com.central.common.util.SysUserUtil;
import com.central.common.util.ToolUtil;
import com.central.common.web.Result;
import com.central.redis.util.RedisUtil;
import com.deepoove.poi.util.TableTools;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author JHY
 */
@Slf4j
@Api(tags = "poi模板生成")
@CrossOrigin
@RestController
@RequestMapping("/poi")
public class PoiController {

    @Autowired
    private OnlineEditService onlineEditService;

    @Autowired
    private HandlerService handlerService;
    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private CheckConNodeService checkConNodeService;
    @Autowired
    private FileSynUtilService fileSynUtilService;
    @Value("${files.docservice.url.site}")
    private String officeUrl;

    @PostMapping("/printTemp")
    public Result<?> printTemp(@RequestBody Map<String, Object> map, HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println(">> enter printTemp <<");
        System.out.println("map :" + JSON.toJSONString(map));
        String access_token = MapUtil.getStr(map, "access_token");
        String docurl = MapUtil.getStr(map, "docurl");

        Map<String, Object> tempData = (Map<String, Object>) map.get("tempData");
        List<Map<String, Object>> childrensInfo = (List<Map<String, Object>>) map.get("childrensInfo");
        String app = MapUtil.getStr(map, "app");
        String id = MapUtil.getStr(map, "id");
        String tempId = MapUtil.getStr(tempData, "id");
        List<Map<String, Object>> fileList =
                handlerService.findBySql("select * from tb_file where appname = 'printtemplateApp' AND isshow=1 AND recordid =" + tempId + " ORDER BY `uploadtime` DESC");
        if (fileList.size() <= 0) {
            return Result.failed("模板文件无空");
        }
        String filePath = "/home/eam/doclinks";
//        String filePath = "D:/test";
        String filepath = MapUtil.getStr(fileList.get(0), "filepath");
        String filerealname = MapUtil.getStr(fileList.get(0), "filerealname");
        filePath += filepath;

        String outputPath = filePath + "outputPath.docx";
        replaceWord(filePath, outputPath, map, "${", "}");
        // 生成审批流程
        String isapprovalprocess = MapUtil.getStr(tempData, "isapprovalprocess");
        if (StringUtils.isNotBlank(isapprovalprocess) && "是".equals(isapprovalprocess)) {
            FileInputStream fis = new FileInputStream(outputPath);
            XWPFDocument document = new XWPFDocument(fis);
            List<Map<String, Object>> list =
                    handlerService
                            .findBySql("select nodename,nickname,opinion,(SELECT field1 FROM sys_user WHERE id=userid) as sign from biz_flow_opinion where app= '" + app + "' and bizid=" + id);
            if (list.size() > 0) {
                XWPFTable table2 = document.createTable();
                // 设置表格边距
                table2.setCellMargins(0, 100, 0, 0);
                table2.setWidth("100%");
                XWPFTableRow row1 = table2.getRow(0);
                XWPFTableCell cell = row1.getCell(0);
                row1.addNewTableCell().setText("审批节点");
                row1.addNewTableCell().setText("审批人");
                row1.addNewTableCell().setText("审批意见");
                row1.addNewTableCell().setText("审批签名");
                row1.getCell(0).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                row1.getCell(1).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                row1.getCell(2).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                row1.getCell(3).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                row1.getCell(4).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                //水平居中
                XWPFParagraph xwpfParagraph0 = cell.addParagraph();
//                //垂直居中
//                xwpfParagraph0.setAlignment(ParagraphAlignment.CENTER);
                //水平居中
                xwpfParagraph0.setVerticalAlignment(TextAlignment.BOTTOM);
                XWPFRun run0 = xwpfParagraph0.createRun();
                run0.setText("审批流程");
                run0.setFontSize(12);
                run0.setBold(true);
                // 设置垂直居中
                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                for (Map<String, Object> item1 : list) {
                    XWPFTableRow row2 = table2.createRow();
                    for (Map.Entry<String, Object> entry : item1.entrySet()) {
                        String key = entry.getKey();
                        String value = entry.getValue().toString();
                        if (key.equals("nodename")) {
                            row2.getCell(1).setText(value);
                        } else if (key.equals("nickname")) {
                            row2.getCell(2).setText(value);
                        } else if (key.equals("opinion")) {
                            row2.getCell(3).setText(value);
                        } else if (key.equals("sign")) {
                            try {
                                //将图片按原始尺寸添加到单元格
                                URL url = new URL(value);
                                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                                conn.setRequestMethod("GET");
                                conn.setConnectTimeout(10 * 1000);
                                InputStream inStream = conn.getInputStream();
                                XWPFParagraph p1 = row2.getCell(4).addParagraph();
                                XWPFRun r1 = p1.createRun();
                                r1.addPicture(inStream, XWPFDocument.PICTURE_TYPE_PNG,
                                        "1.png", Units.toEMU(60), Units.toEMU(30));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    row2.getCell(0).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                    row2.getCell(1).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                    row2.getCell(2).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                    row2.getCell(3).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                    row2.getCell(4).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1600));
                }
                TableTools.mergeCellsVertically(table2, 0, 0, list.size());
                document.write(new FileOutputStream(outputPath));
            }
        }

        String pdfPath = outputPath + ".pdf";
        if (childrensInfo != null && childrensInfo.size() > 0) {

            FileInputStream fis = new FileInputStream(outputPath);
            XWPFDocument doc = new XWPFDocument(fis);
//        // 获取第一个表格
            List<XWPFTable> tables = doc.getTables();
            if (tables.size() > 0) {
                XWPFTable table = doc.getTables().get(0);
                XWPFTableRow row = table.getRow(1);

                for (int i = 0; i < childrensInfo.size() - 1; i++) {
                    // 复制整行并插入到第二行位置
                    XWPFTableRow newRow = table.insertNewTableRow(i + 1);
//            //复制行属性
                    newRow.getCtRow().set(row.getCtRow());
                }
                FileOutputStream fos = new FileOutputStream(outputPath);
                doc.write(fos);
                doc.close();
                fos.close();
                fis.close();

                FileInputStream fis2 = new FileInputStream(outputPath);
                XWPFDocument doc2 = new XWPFDocument(fis2);
                XWPFTable table2 = doc2.getTables().get(0);
                List<XWPFTableRow> rows2 = table2.getRows();
                System.err.println("表格行数:" + rows2.size());
                for (int i = 0; i < rows2.size() - 1; i++) {
                    Map<String, Object> tmpMap = childrensInfo.get(i);
                    System.err.println(tmpMap + "---" + (i + 1));
                    List<XWPFTableCell> tableCells = table2.getRow((i + 1)).getTableCells();
                    for (XWPFTableCell tableCell : tableCells) {
                        String text = tableCell.getText();
                        System.err.println(text);
                        if ("${num}".equals(text)) {
                            // 获取当前单元格的段落对象
                            XWPFParagraph paragraph = tableCell.getParagraphs().size() > 0 ? tableCell.getParagraphs().get(0) : tableCell.addParagraph();
                            // 清空段落内容
                            paragraph.removeRun(0);
                            // 在段落中添加文本
                            XWPFRun run = paragraph.createRun();
                            run.setText((i + 1) + "");
                        }

                        for (Map.Entry<String, Object> entry : tmpMap.entrySet()) {
                            String key = "${" + entry.getKey() + "}";
                            String value = entry.getValue().toString();
                            if (key.equals(text)) {
                                // 获取当前单元格的段落对象
                                XWPFParagraph paragraph = tableCell.getParagraphs().size() > 0 ? tableCell.getParagraphs().get(0) : tableCell.addParagraph();
                                // 清空段落内容
                                paragraph.removeRun(0);
                                // 在段落中添加文本
                                XWPFRun run = paragraph.createRun();
                                run.setText(value);
                            }
                        }
                    }
                }

                FileOutputStream fos2 = new FileOutputStream(outputPath);
                doc2.write(fos2);
                doc2.close();
                fos2.close();
                fis2.close();
            }

//            WordToPdfUtil.docToPdf(outputPath, pdfPath);
        }
//        else {
//            WordToPdfUtil.docToPdf(outputPath, pdfPath);
//        }
        WordToPdfUtil.docToPdf(outputPath, pdfPath);
//        // 定义重试次数和间隔时间
//        int maxRetryTime = 3;
//        int retryInterval = 1000; // 单位为毫秒
//        int retryCount = 0;
//
//        for (retryCount = 0; retryCount < maxRetryTime; retryCount++) {
//            try {
//                // 发送 word 转 pdf 的请求并下载文件
//                Map<String, Object> rsp = new HashMap<>();
//                rsp.put("async", false);
//                rsp.put("filetype", "docx");
//                rsp.put("key", IdUtil.fastSimpleUUID());
//                rsp.put("outputtype", "pdf");
//                rsp.put("title", filerealname);
//                rsp.put("url", docurl + "/api-apps/archiveGeneration/downloadDoc?access_token=" + access_token + "&path=" + outputPath);
//                System.out.println("rsp:" + JSON.toJSONString(rsp));
//                URL url = new URL(officeUrl + "ConvertService.ashx");
//                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//                connection.setRequestMethod("POST");
//                connection.setRequestProperty("Content-Type", "application/json");
//                connection.setRequestProperty("Accept", "application/json");
//                connection.setDoOutput(true);
//                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream());
//                outputStreamWriter.write(JSON.toJSONString(rsp));
//                outputStreamWriter.flush();
//                outputStreamWriter.close();
//                int responseCode = connection.getResponseCode();
//                if (responseCode != 200) {
//                    continue;
//                }
//                System.out.println("Response Code : " + responseCode);
//                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//                String inputLine;
//                StringBuffer sb = new StringBuffer();
//                while ((inputLine = in.readLine()) != null) {
//                    sb.append(inputLine);
//                }
//                in.close();
//                String docres = sb.toString();
//                if (StringUtils.isBlank(docres)) {
//                    continue;
//                }
//                // Print response data
//                System.out.println("docres" + docres);
//                Map<String, Object> resMap = JSONObject.parseObject(docres);
//                System.out.println("resMap:" + resMap);
//
//                String fileUrl = MapUtil.getStr(resMap, "fileUrl");
//                if (StringUtils.isBlank(fileUrl)) {
//                    continue;
//                }
//                System.out.println("fileUrl:" + fileUrl);
//
//                InputStream inputStream = null;
//                FileOutputStream outputStream = null;
//                try {
//                    URL durl = new URL(fileUrl);
//                    URLConnection dconnection = durl.openConnection();
//                    inputStream = dconnection.getInputStream();
//                    outputStream = new FileOutputStream(outputPath + "-OnlyOffice.pdf");
//                    byte[] buffer = new byte[2048];
//                    int length;
//                    while ((length = inputStream.read(buffer)) != -1) {
//                        outputStream.write(buffer, 0, length);
//                    }
//                    break;
//                } catch (IOException e) {
//                    e.printStackTrace();
//                } finally {
//                    if (inputStream != null) {
//                        inputStream.close();
//                    }
//                    if (outputStream != null) {
//                        outputStream.close();
//                    }
//                }
//
//            } catch (Exception e) {
//                // 操作失败，打印异常信息
//                e.printStackTrace();
//                System.out.println("Word 转 PDF 操作失败，开始第 " + (retryCount + 1) + " 次重试...");
//                // 等待一定时间后进行下一次重试
//                try {
//                    Thread.sleep(retryInterval);
//                } catch (InterruptedException ex) {
//                    ex.printStackTrace();
//                }
//            }
//        }
//        // 如果重试次数仍然失败，抛出异常
//        if (retryCount > maxRetryTime) {
//            throw new RuntimeException("Word 转 PDF 操作失败，已尝试最大重试次数。");
//        }

        //保存为PDF格式
        return Result.succeed(pdfPath, "打印成功");

    }

    @PostMapping("/tmpGenerate")
    public void tmpGenerate(@RequestBody Map<String, Object> map, HttpServletRequest request, HttpServletResponse response) {
        System.out.println(">> enter tmpGenerate <<");
        System.out.println("map :" + JSON.toJSONString(map));
        String concode = MapUtils.getString(map, "concode");
        String tablename = "gq_consigns";
        String app = "consignsApp";
        if (ToolUtil.isEmpty(concode)) {
            tablename = "gq_conapplication";
            app = "conapplicationApp";
        }

        long id = MapUtils.getIntValue(map, "id");
        List<Map<String, Object>> list2 = handlerService.findBySql("select * from " + tablename + " where id = " + id);
        if (CollectionUtils.isNotEmpty(list2)) {
            map = list2.get(0);
            String dates = DateUtiles.getYmd((Date) list2.get(0).get("createtime"));
            map.put("dates", dates);
        }
        //获取当前登录人用户名称
        LoginAppUser user = SysUserUtil.getLoginAppUser();
        //部门编码
        String deptcode = user.getDeptcode();
        String username = user.getUsername();
        String deptName = user.getDeptName();
        if (ToolUtil.isEmpty(deptName)) {
            List<Map<String, Object>> deptList = handlerService.findBySql("select fullname from sys_dept where code ='" + deptcode + "'");
            if (CollectionUtils.isNotEmpty(deptList)) {
                deptName = MapUtils.getString(deptList.get(0), "fullname");
            }
        }
        Long userid = user.getId();

        System.out.println(JSON.toJSONString(user));

        Map<String, String> rsp = new HashMap();
        // 合同名称
        String conname = MapUtil.getStr(map, "conname");
        Long recordid = MapUtil.getLong(map, "id");
        List<Map<String, Object>> conlist = handlerService.findBySql("select conid from gq_conapplication where id = " + recordid);
        int conid = MapUtils.getIntValue(conlist.get(0), "conid");
        // 合同模板ID
        String contemplate = MapUtil.getStr(map, "contemplate");
        if (ToolUtil.isEmpty(contemplate)) {
            contemplate = "1117";
        }
        if (StringUtils.isBlank(contemplate)) {
            rsp.put("resp_code", HttpStatus.INTERNAL_SERVER_ERROR.value() + "");
            rsp.put("resp_msg", "合同模板ID不能为空!");
            ResponseUtil.renderJsonError(response, rsp, HttpStatus.INTERNAL_SERVER_ERROR.value());
            return;
        }
        //List<Map<String, Object>> mapList = new ArrayList<>();
        Map<String, Object> mapnew = new HashMap<>();
        String appname = MapUtil.getStr(map, "app");
        boolean ispocon = false;
        Map<String, Object> huizongmap = new HashMap<>();
        int ponum = 0;
        String key = appname + recordid;
        if (appname == null || "".equals(appname)) {
            appname = app;

        } else {
            ispocon = true;
            //根据appname,id,文件名，判断是否已经生成过

            if (redisUtil.hasKey(key)) {
                rsp.put("resp_code", HttpStatus.INTERNAL_SERVER_ERROR.value() + "");
                rsp.put("resp_msg", "采购合同已生成，不能重复生成");
                ResponseUtil.renderJson(response, rsp);
                return;
            }
            List<Map<String, Object>> polist = handlerService.findBySql("select suppliername from gq_po where id = '" + recordid + "'");
            if (CollectionUtils.isNotEmpty(polist)) {
                //供应商名称
                mapnew.put("suppliername", polist.get(0).get("suppliername"));
                //订单编号
                mapnew.put("ponum", MapUtil.getStr(map, "concode"));
            }
            List<Map<String, Object>> list = handlerService.findBySql("select * from gq_posline where poid = '" + recordid + "'");
            if (CollectionUtils.isNotEmpty(list)) {
                ponum = list.size();
                double totalcosts = 0.00;
                for (int i = 0; i < list.size(); i++) {
                    mapnew.put("itemdesc" + i, list.get(i).get("itemdesc"));
                    mapnew.put("spemodel" + i, list.get(i).get("spemodel"));
                    mapnew.put("maintechtors" + i, list.get(i).get("maintechtors"));
                    mapnew.put("orderunit" + i, list.get(i).get("orderunit"));
                    mapnew.put("orderqty" + i, list.get(i).get("orderqty"));
                    mapnew.put("unitcost" + i, list.get(i).get("unitcost"));
                    mapnew.put("totalcost" + i, list.get(i).get("totalcost"));
                    mapnew.put("unitcost" + i, list.get(i).get("unitcost"));
                    totalcosts = totalcosts + (float) list.get(i).get("totalcost");
                    //mapList.add(mapnew);
                }
                conname = "采购合同";
                DecimalFormat decimalFormat = new DecimalFormat(".00");
                String p = decimalFormat.format(totalcosts);
                String totalcostup = worldUtil.numberConvertAmount(p);
                mapnew.put("totalcosts", p);
                mapnew.put("totalcostup", totalcostup);


                //mapList.add(huizongmap);
            }
        }

        // 设置当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        map.put("currentTime", sdf.format(new Date()));

        List<Map<String, Object>> templateList = handlerService.findBySql("select * from gq_contemplate where tecode =" + contemplate + "");
        String tmpId = MapUtil.getStr(templateList.get(0), "id");

        List<Map<String, Object>> fileList = handlerService.findBySql("select * from tb_file where appname = 'contemplateApp' and recordid =" + tmpId + "");
        String pathname = MapUtil.getStr(fileList.get(0), "filepath");
        String pathid = MapUtil.getStr(fileList.get(0), "pathid");
        // 文件原名称
        String filerealname = MapUtil.getStr(fileList.get(0), "filerealname");
        // 文件md5值
        String md5 = MapUtil.getStr(fileList.get(0), "md5");
        String fileUserId = MapUtil.getStr(fileList.get(0), "userid");
        String fileUserName = MapUtil.getStr(fileList.get(0), "username");
        // 文件扩展名
        String extensionname = MapUtil.getStr(fileList.get(0), "extensionname");
        // 文件大小
        String filesize = MapUtil.getStr(fileList.get(0), "filesize");

        List<Map<String, Object>> pathList = handlerService.findBySql("select * from tb_path where pathid =" + pathid + "");
        String filepath = MapUtil.getStr(pathList.get(0), "pathname");
        if (StringUtils.isNotBlank(pathname)) {
            String[] split = pathname.split("/");
            pathname = "/" + split[split.length - 1];
        }
        String pt = filepath + pathname;
        System.out.println(">>>>>>>>>>>>>>>>>>>> 文件路径: " + pt);
        if (ispocon && ponum > 1) {
            //根据查询条数，动态修改world模板
            worldUtil.setWorldTable(ponum - 1, pt);
        }
        if (ispocon && ponum == 1) {
            pt = "/home/eam/doclinks/综合管理部/world.docx";
        }
        if (ispocon && ponum == 0) {
            pt = "/home/eam/doclinks/综合管理部/world1.docx";
        }
//        ServletOutputStream outputStream = null;

        InputStream is = null;
        OutputStream os = null;
        try {
            //pt="C:\\Users\\86136\\Desktop\\新建文件夹\\合同模板.docx";
            is = new FileInputStream(pt);
            XWPFDocument doc = new XWPFDocument(is);
            if (!ispocon) {
                //替换段落里面的变量
                replaceInPara(doc, map);
                //替换表格里面的变量
                replaceInTable(doc, map);
            }
//            //响应防止乱码
//            response.setContentType("application/docx");
//            // 传递中文参数编码
//            response.setHeader("content-disposition", "attachment;filename=" + conname + ".docx");
//            outputStream = response.getOutputStream();
//            doc.write(outputStream);

            String uid = IdUtil.simpleUUID();
            SimpleDateFormat sdft = new SimpleDateFormat("yyyy-MM-dd");
            String formatNowDate = sdft.format(new Date());
            String fileName = formatNowDate + "_" + uid + "." + extensionname;

            if (ispocon) {
                // 模板word文件真实路径
                String wordSrcPath = pt;
                // 使用该办件编号作为文件名称
                String wordDestPath = "/home/eam/doclinks/" + deptName + "/" + fileName;
                try {
                    POIUtil.templateWrite(wordSrcPath, wordDestPath, mapnew);
                    redisUtil.set(key, "true");
                } catch (Exception e) {
                    e.printStackTrace();
                }
//                for (Map<String, Object> stringObjectMap : mapList) {
//
//                    try {
//                        POIUtil.templateWrite(wordSrcPath, wordDestPath, mapnew);
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }
//                try {
//                    POIUtil.templateWrite(wordSrcPath, wordDestPath, huizongmap);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }

            } else {
//                os = new FileOutputStream("/home/eam/doclinks/科技发展部/" + fileName);
//                doc.write(os);
                POIUtil.templateWrite(pt, "/home/eam/doclinks/" + deptName + "/" + fileName, map);
            }

            String pathsql = "select pathid from tb_path where foldername  = '" + deptName + "'";
            List<Map<String, Object>> pathLists = handlerService.findBySql(pathsql);
            int pathids = 0;
            if (CollectionUtils.isNotEmpty(pathLists)) {
                pathids = MapUtils.getIntValue(pathLists.get(0), "pathid");
            }
            TBFile tbFile = new TBFile();
            tbFile.setPathid(pathids);
            if (StringUtils.isNotBlank(deptcode)) {
                tbFile.setDeptid(deptcode);
            }
            if (StringUtils.isNotBlank(deptName)) {
                tbFile.setDeptfullname(deptName);
            } else {
                tbFile.setDeptfullname("科技发展部");
            }
            if (userid != null) {
                tbFile.setUserid(String.valueOf(userid));
            }
            if (StringUtils.isNotBlank(username)) {
                tbFile.setUsername(username);
            }

            String fileMd5 = FileUtil.fileMD5(new File("/home/eam/doclinks/" + deptName + "/" + fileName));
            tbFile.setUploadtime(new Date());
            tbFile.setFilesize(new BigDecimal(filesize));
            tbFile.setFilepath("/" + deptName + "/" + fileName);
            tbFile.setExtensionname(extensionname);
            tbFile.setAppid(595);
            // consignApp contemplateApp
            tbFile.setAppname(appname);
            tbFile.setRecordid(recordid);
            tbFile.setFilestatus("已发布");
            tbFile.setStatustime(new Date());
            tbFile.setFilename(conname + "_v1.0");
            // filerealname
            tbFile.setFilerealname(conname + "_v1.0" + "." + extensionname);
            tbFile.setFileversion(1);
            tbFile.setMd5(fileMd5);
            tbFile.setSecretkey("");
            tbFile.setIsshow(1);
            //增加前先进行删除旧合同文件
            handlerService.updateBySql("update  tb_file set isshow=0  where appname = '" + appname + "' and filerealname = '" + tbFile.getFilerealname() + "' and recordid = " + recordid);

            checkConNodeService.insertConfiles(tbFile);
            //如果是合同申请生成的合同，需要同步到合同台账
            //将上传的文件插入到合同台账的
            //fileSynUtilService.insertFiles(app, id, conid, tbFile.getFilerealname());


        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(">>>>>>>>>>>>>>>>>>>> ERROR: " + e.getMessage());
            rsp.put("resp_code", HttpStatus.INTERNAL_SERVER_ERROR.value() + "");
            rsp.put("resp_msg", "模板生成失败!");
            ResponseUtil.renderJsonError(response, rsp, HttpStatus.INTERNAL_SERVER_ERROR.value());
        } finally {
//            if (outputStream != null) {
//                try {
//                    outputStream.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        rsp.put("resp_code", HttpStatus.INTERNAL_SERVER_ERROR.value() + "");
        rsp.put("resp_msg", "合同文本生成成功");
        if (response != null) {
            ResponseUtil.renderJson(response, rsp);
        }


    }

    /**
     * 替换段落里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     */
    private static void replaceInPara(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph para;
        while (iterator.hasNext()) {
            para = iterator.next();
            replaceInPara(para, params);
        }
    }


    /**
     * 替换段落里面的变量
     *
     * @param para   要替换的段落
     * @param params 参数
     */
    private static void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
        List<XWPFRun> runs;
        Matcher matcher;
        if (matcher(para.getParagraphText()).find()) {
            runs = para.getRuns();
            for (int i = 0; i < runs.size(); i++) {
                XWPFRun run = runs.get(i);
                String runText = run.toString();
                matcher = matcher(runText);
                if (matcher.find()) {
                    while ((matcher = matcher(runText)).find()) {
                        runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
                    }
                    //直接调用XWPFRun的setText()方法设置文本时，在底层会重新创建一个XWPFRun，把文本附加在当前文本后面，
                    //所以我们不能直接设值，需要先删除当前run,然后再自己手动插入一个新的run。
                    para.removeRun(i);
                    para.insertNewRun(i).setText(runText);
                }
            }
        }
    }

    /**
     * 替换表格里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     */
    private static void replaceInTable(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFTable> iterator = doc.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
        while (iterator.hasNext()) {
            table = iterator.next();
            rows = table.getRows();
            for (XWPFTableRow row : rows) {
                cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        replaceInPara(para, params);
                    }
                }
            }
        }
    }

    /**
     * 正则匹配字符串
     *
     * @param str
     * @return
     */
    private static Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }

    /**
     * 关闭输入流
     *
     * @param is
     */
    private static void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭输出流
     *
     * @param os
     */
    private static void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 替换word变量
     *
     * @param wordPath   模板路径
     * @param outputPath 输出路径
     * @param varMap     变量Map
     * @param prefix     前缀
     * @param suffix     后缀
     */
    public static void replaceWord(String wordPath, String outputPath, Map<String, Object> varMap, String prefix, String suffix) {
        FileInputStream fis = null;
        XWPFDocument doc = null;
        FileOutputStream fos = null;

        try {
            // 读取模板文件
            fis = new FileInputStream(wordPath);
            doc = new XWPFDocument(fis);
            // 替换模板中的变量
            for (XWPFParagraph paragraph : doc.getParagraphs()) {
                for (XWPFRun run : paragraph.getRuns()) {
                    String text = run.getText(0);
                    if (text != null) {
                        for (Map.Entry<String, Object> entry : varMap.entrySet()) {
                            String key = entry.getKey();
                            text = text.replace(prefix + key + suffix, entry.getValue().toString());
                        }
                        run.setText(text, 0);
                    }
                }
            }
            // 保存文档
            fos = new FileOutputStream(outputPath);
            doc.write(fos);
        } catch (IOException e) {
            System.out.println("替换word变量异常:" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (doc != null) {
                try {
                    doc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("替换完成");
        }
    }


    //导入模板下载
    @PostMapping("/importTemplate")
    public Result importTemplate(@RequestBody Map<String, Object> map, HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            String filePath = "/home/eam/doclinks";
            String urlname = "";

            String app = MapUtils.getString(map, "app");
            String sql = "select * from gq_printtemplate where appnum = '" + app + "'";
            List<Map<String, Object>> bySql = handlerService.findBySql(sql);

            String tempId = MapUtils.getString(bySql.get(0), "id");
            String sql1 = "select * from tb_file where appname = 'printtemplateApp' AND isshow=1 AND recordid =" + tempId + " ORDER BY `uploadtime` DESC";
            List<Map<String, Object>> bySql1 = handlerService.findBySql(sql1);
            if(CollectionUtils.isEmpty(bySql1)){
                return Result.failed("该功能没有设置导入模板，请检查。");
            }
            String filepath = MapUtils.getString(bySql1.get(0), "filepath");
            String filerealname = MapUtils.getString(bySql1.get(0), "filerealname");
            urlname = filePath + filepath;
            System.err.println("来咯，看看路径-------------------------"+urlname);
            File file = new File(urlname);
            if (!file.exists()) {
                String errorMessage = "Sorry. The file you are looking for does not exist";
                System.out.println(errorMessage);
                OutputStream outputStream = response.getOutputStream();
                outputStream.write(errorMessage.getBytes(Charset.forName("UTF-8")));
                outputStream.close();
                return Result.failed(errorMessage);
            }


            byte[] encodeBytes = com.central.apps.util.FileUtil.getByte(file);
            byte[] decryptEcb = encodeBytes;
            String fileNameURL = URLEncoder.encode(filerealname, "UTF-8");
            response.reset();
            response.setHeader("Content-disposition", "attachment;filename="+fileNameURL+";"+"filename*=utf-8''"+fileNameURL);
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);

            response.setContentLength(decryptEcb.length);
            // 指向response的输出流
            OutputStream os = response.getOutputStream();
            os.write(decryptEcb, 0, decryptEcb.length);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.succeed("模板下载成功。");
    }

}
